x/exp/schema: fix reserved keyword handling and add validation#130
Merged
patjakdev merged 1 commit intocedar-policy:mainfrom Feb 10, 2026
Merged
x/exp/schema: fix reserved keyword handling and add validation#130patjakdev merged 1 commit intocedar-policy:mainfrom
patjakdev merged 1 commit intocedar-policy:mainfrom
Conversation
Add a tokenReservedKeyword token type to the schema parser's lexer, matching the approach used in the main Cedar parser. Previously, reserved keywords like "true", "false", "in", "if", etc. were lexed as plain identifiers, which meant the parser silently accepted them in positions where they should be rejected (e.g. `entity true;`, `type if = String;`).
Bugs fixed:
- Reserved Cedar keywords were accepted as entity, type, and action names, namespace path components, and attribute names without quoting. The parser now rejects these with a clear error message.
- __cedar as a definition name (entity, type, enum) was silently accepted. These are now rejected while still allowing __cedar as an action name, attribute name, and type reference prefix, which matches the Cedar Rust behavior.
- Duplicate annotations (e.g. `@doc("a") @doc("b")`) were silently accepted with last-wins semantics. The parser now rejects duplicates.
- Duplicate principal, resource, or context declarations within appliesTo were silently accepted. The parser now rejects duplicates.
- Empty principal or resource type lists in appliesTo (e.g. `principal: []`) were silently accepted, producing a meaningless empty list. The parser now rejects these.
- appliesTo blocks missing a principal or resource declaration were accepted. The parser now requires both.
- MarshalSchema emitted reserved keywords as bare identifiers in attribute and action names (e.g. `true: String`), producing output that could not be re-parsed. isValidIdent now checks for reserved keywords and the marshaler quotes them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-Off-By: Patrick Jakubowski <patrick.jakubowski@strongdm.com>
490ec1e to
4217868
Compare
patjakdev
commented
Feb 10, 2026
| Text string | ||
| } | ||
|
|
||
| // N.B. "is" is included here for compatibility with the Rust implementation. The Cedar specification does not list |
Collaborator
Author
There was a problem hiding this comment.
is is now in the official documentation
| // N.B. "is" is included here for compatibility with the Rust implementation. The Cedar specification does not list | ||
| // "is" as a reserved keyword | ||
| var reservedKeywords = []string{"true", "false", "if", "then", "else", "in", "like", "has", "is"} | ||
| var reservedKeywords = []string{"true", "false", "if", "then", "else", "in", "like", "has", "is", "__cedar"} |
Collaborator
Author
There was a problem hiding this comment.
At some point, they added __cedar as a reserved keyword in the policy schema
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue #, if available:
Description of changes:
Add a tokenReservedKeyword token type to the schema parser's lexer, matching the approach used in the main Cedar parser. Previously, reserved keywords like "true", "false", "in", "if", etc. were lexed as plain identifiers, which meant the parser silently accepted them in positions where they should be rejected (e.g.
entity true;,type if = String;).Bugs fixed:
__cedaras a definition name (entity, type, enum) was silently accepted. These are now rejected while still allowing__cedaras an action name, attribute name, and type reference prefix, which matches the Cedar Rust behavior.@doc("a") @doc("b")) were silently accepted with last-wins semantics. The parser now rejects duplicates.principal,resource, orcontextdeclarations withinappliesTowere silently accepted. The parser now rejects duplicates.principalorresourcetype lists inappliesTo(e.g.principal: []) were silently accepted, producing a meaningless empty list. The parser now rejects these.appliesToblocks missing aprincipalorresourcedeclaration were accepted. The parser now requires both.MarshalSchema()emitted reserved keywords as bare identifiers in attribute and action names (e.g.true: String), producing output that could not be re-parsed.isValidIdent()now checks for reserved keywords and the marshaler quotes them.